import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Checkbox, Button } from 'antd';
import PropTypes from 'prop-types';

import './table.scoped.less';

import VirtualScroll from '@/components/virtualScrolling/VirtualScroll.jsx';
import a, { Tip } from '@/components/tip/Tip.jsx';

export default class Table extends Component {
  static propTypes = {
    primaryKey: PropTypes.string,
    tableData: PropTypes.array.isRequired,
    selectMode: PropTypes.string, // 表格选中
    trClass: PropTypes.func, // tr
    tdClass: PropTypes.func, // td类名
    trEvent: PropTypes.object, // tr事件
    selectHighlight: PropTypes.bool, // 是否选中高亮
    stripe: PropTypes.bool, // 表格是否带条纹
    selectKey: PropTypes.array, // 设置表格默认勾选
    itemHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // 每一项的高度
    align: PropTypes.string, // 对其方式
  };

  static defaultProps = {
    // itemHeight: 0, // 滚动的高度
    checkbox: true,
    align: 'left',
    trClass: () => {
      return '';
    },
    tdClass: () => {
      return '';
    },
    trEvent: {},
    selectHighlight: true,
    stripe: true,
    selectKey: [],
  };

  state = {
    tableColumn: [],
    tableData: this.props.tableData,
    tableHeadOverflowY: 'auto',
    allSelect: false, // 是否全选
    selectKey: [], // 已勾选的数据，取this.primaryKey字段
    itemHeight: this.props.itemHeight,
    trEvent: {
      onClick: (item, index) => {
        const { primaryKey } = this.props;
        const { selectKey } = this.state;
        item._checked = !item._checked;
        // 设置点击行选中
        const key = primaryKey ? item[primaryKey] : index;
        if (item._checked && !selectKey.includes(key)) {
          selectKey.push(key);
        } else {
          const keyIndex = selectKey.findIndex((k) => k === key);
          if (keyIndex !== -1) {
            selectKey.splice(keyIndex, 1);
          }
        }
        this.setState({ selectKey, allSelect: selectKey.length === this.state.tableData.length });
        // 向上传递勾选的数据
        this.handUpSelectKey({ selectKey });
      },
      onDoubleClick: () => {},
      ...this.props.trEvent,
    },
    tip: null, // 提示的dom节点
    timer: null, // 定时器
    tipTimer: null, // 提示的定时器
    tipList: [], // 保存提示的dom，滚动时删除
  };

  refTable = React.createRef(); // 表格内容滚动的盒子
  refTableHead = React.createRef();

  UNSAFE_componentWillReceiveProps = (nextProps) => {
    const { state, props } = this;
    // 初始化表格
    if (nextProps.tableData !== this.props.tableData) {
      this.state.selectKey = []; // 表格数据改变时设置选中项为空
      this.state.tableData = nextProps.tableData.map((item, index) => {
        item._checked = false;
        item._index = index;
        return item;
      });
    }
    // 设置默认勾选
    if (props.selectKey !== nextProps.selectKey) {
      this.initSelectData(nextProps); // 初始化默认勾选数据
    }
  };

  componentDidMount = () => {
    this.initSelectData(); // 初始化默认勾选数据
  };
  // 清除提示
  clearTip = () => {
    this.state.tipList.forEach((item) => {
      if (item) {
        try {
          item.parentElement.removeChild(item);
        } catch (error) {}
        item = null;
      }
    });
    this.state.tipList = [];
  };
  tableScrollMouseLeave = () => {
    setTimeout(() => {
      this.clearTip();
    }, 300);
  };
  // 文字超出鼠标移入显示提示框加载
  textMouseEnter = (value, e) => {
    clearTimeout(this.timer);
    clearTimeout(this.tipTimer);

    this.timer = setTimeout(() => {
      this.clearTip();
      const { scrollWidth, clientWidth } = e.target;

      if (scrollWidth > clientWidth) {
        // 提示框鼠标移出
        const tipMouseLeave = (dom) => {

          this.tipTimer = setTimeout(() => {

            this.clearTip();
            clearTimeout(this.timer);
          }, 200);
        };
        // 提示框鼠标移入
        const tipMouseEnter = () => {
          setTimeout(() => {

            clearTimeout(this.tipTimer);
          }, 20);
        };
        let div = document.createElement('div');
        this.state.tipList.push(div);

        // 鼠标离开时
        e.target.onmouseleave = () => {

          this.tipTimer = setTimeout(() => {

            this.clearTip();
          }, 200);
        };

        document.body.appendChild(div);
        ReactDOM.render(
          <Tip
            dom={e.target}
            value={value}
            onMouseLeave={() => tipMouseLeave(div)}
            onMouseEnter={() => tipMouseEnter(div)}
          ></Tip>,
          div
        );
      }
    }, 300);
  };

  // 初始化默认勾选数据
  initSelectData = (nextProps) => {
    const props = nextProps || this.props;
    let { tableData, selectKey, allSelect } = this.state;
    if (props.primaryKey) {
      // 如果设置了位置值
      this.state.tableData.forEach((item) => {
        if (selectKey.includes(item[props.primaryKey])) {
          item._checked = true;
        }
      });
    } else {
      // 如果设置了位置值
      tableData.forEach((item, index) => {
        if (selectKey.includes(index)) {
          item._checked = true;
        }
      });
    }
    // 判断是不是全选
    if (selectKey.length === tableData.length) {
      allSelect = true;
    }
    this.setState({ allSelect, selectKey });
  };
  // 表格滚动
  tableScroll = ({ scrollLeft, clientHeight, scrollHeight }) => {
    // 设置横向滚动时表头一起滚动
    this.refTableHead.current.scrollLeft = scrollLeft;
    // 设置表头是否要显示滚动条
    if (scrollHeight > clientHeight && this.state.tableHeadOverflowY !== 'scroll') {
      this.setState({ tableHeadOverflowY: 'scroll' });
    }
    // 如果有提示就关闭提示
    this.clearTip();
  };
  // 点击全选
  allSelectChange = (e) => {
    const { checked } = e.target;

    // 设置选中的数据
    let selectKey = [];
    if (checked) {
      selectKey = this.state.tableData.map((item, index) => {
        item._checked = true; // 设置表格数据选中
        if (this.props.primaryKey) {
          return item[this.props.primaryKey];
        }
        return index;
      });
    } else {
      selectKey = [];
      this.state.tableData.forEach((item, index) => {
        item._checked = false; // 设置表格数据取消选中
      });
    }
    this.setState({ selectKey, allSelect: selectKey.length === this.state.tableData.length });

    // 向上传递勾选的数据
    this.handUpSelectKey({ selectKey });
  };
  // 点击勾选
  selectSingle = (item, index, e) => {
    e.stopPropagation();
    const { checked } = e.target;
    // 设置当前勾选项是否选中
    if (checked) {
      item._checked = true;
    } else {
      item._checked = false;
    }

    const key = this.props.primaryKey ? item[this.props.primaryKey] : index;
    const { selectKey } = this.state;
    // 如果选中了就取消选中，没选中就勾选
    const keyIndex = selectKey.findIndex((item) => item === key);
    if (keyIndex === -1) {
      selectKey.push(key);
    } else {
      selectKey.splice(keyIndex, 1);
    }

    // 设置表头全选是否勾选
    this.setState({ allSelect: selectKey.length === this.state.tableData.length, selectKey });
    // 向上传递勾选的数据
    this.handUpSelectKey({ selectKey });
  };
  // 向上传递勾选的数据
  handUpSelectKey = (data) => {
    if (typeof this.props.selectChange === 'function') {
      this.props.allSelectChange(data);
    }
  };

  //

  render() {
    // 表格的宽度
    const tableAllWidth = this.props.tableColumn.reduce((prev, cur) => {
      return prev + parseInt(cur.width);
    }, 0);

    return (
      <div
        className="virtualScroll"
        style={{ width: 500, border: '1px solid red', padding: '20px', overflow: 'auto' }}
      >
        {/* 表头 */}
        <div
          className="show-table-head"
          ref={this.refTableHead}
          style={{ overflowY: this.state.tableHeadOverflowY }}
        >
          <table className="table" style={{ width: tableAllWidth }}>
            <colgroup>
              {this.props.checkbox && <col style={{ width: '50px' }}></col>}
              {this.props.tableColumn.map((item, index) => {
                return <col style={{ width: item.width }} key={index}></col>;
              })}
            </colgroup>
            <thead>
              <tr className="head-tr" style={{ textAlign: this.props.align }}>
                {/* 表头复选框 */}
                {this.props.checkbox && (
                  <th style={{ textAlign: this.props.align }}>
                    <Checkbox checked={this.state.allSelect} onChange={this.allSelectChange}></Checkbox>
                  </th>
                )}
                {/*  */}
                {this.props.tableColumn.map((item, index) => {
                  let value = item.title;

                  // if (typeof item.render === 'function') {
                  //   value = item.render();
                  // }

                  return (
                    <th key={index} style={{ textAlign: this.props.align }}>
                      {value}
                    </th>
                  );
                })}
              </tr>
            </thead>
          </table>
        </div>
        {/*  */}

        <VirtualScroll
          itemHeight={this.props.itemHeight}
          list={this.state.tableData}
          onScroll={this.tableScroll}
          onMouseLeave={this.tableScrollMouseLeave}
        >
          {({ list }) => {
            const tableData = this.props.itemHeight ? list : this.state.tableData;
            return (
              <table className="table" style={{ width: tableAllWidth }}>
                <colgroup>
                  {this.props.checkbox && <col style={{ width: '50px' }}></col>}
                  {this.props.tableColumn.map((item, index) => {
                    return <col style={{ width: item.width }} key={index}></col>;
                  })}
                </colgroup>
                {/* 隐藏的表头-不显示 */}
                {/* <thead>
                  <tr>
                    {this.state.tableColumn.map((item, index) => {
                      let value = 123123;

                      if (typeof item.render === 'function') {
                        value = item.render();
                      }

                      return (
                        <th style={{ border: 'none' }} key={index}>
                          <div style={{ height: 0, overflow: 'hidden' }}>{value}</div>
                        </th>
                      );
                    })}
                  </tr>
                </thead> */}
                {/* 表格内容 */}
                <tbody>
                  {tableData.map((item, index) => {
                    return (
                      <tr
                        key={item._index}
                        style={{ height: this.props.itemHeight ? this.state.itemHeight : 'auto' }}
                        className={`${this.props.trClass(item, item._index)} ${
                          item._checked && this.props.selectHighlight ? 'tr-select' : ''
                        } ${this.props.stripe && item._index % 2 === 0 ? 'tr-stripe' : ''} ${
                          this.props.itemHeight ? 'virtual' : ''
                        }`}
                        onClick={() => this.state.trEvent.onClick(item, item._index)}
                        onDoubleClick={() => this.state.trEvent.onDoubleClick(item, item._index)}
                      >
                        {/* 复选框 */}
                        {this.props.checkbox && (
                          <td
                            className={`${this.props.tdClass(item, item._index)}`}
                            style={{ textAlign: this.props.align }}
                          >
                            <Checkbox
                              checked={item._checked}
                              onChange={(e) => this.selectSingle(item, item._index, e)}
                            ></Checkbox>
                          </td>
                        )}
                        {/*  */}
                        {this.props.tableColumn.map((item2, index2) => {
                          let value = item[item2.field];
                          if (typeof item2.render === 'function') {
                            value = item2.render(value, item, item._index);
                          }
                          return (
                            <td
                              key={index2}
                              className={`${item._index % 2 === 0 ? 'td-bg' : ''} ${this.props.tdClass(
                                item,
                                item._index
                              )}`}
                              style={{ textAlign: this.props.align }}
                            >
                              <div
                                onMouseEnter={(e) => this.textMouseEnter(value, e)}
                                className="text-over"
                                style={{ width: '100%' }}
                              >
                                {value}
                              </div>
                            </td>
                          );
                        })}
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            );
          }}
        </VirtualScroll>

        {/*  */}
      </div>
    );
  }
}
